package com.matt.remoteCall;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.matt.commons.exception.BusinessException;
import com.matt.commons.model.ErrorCode;
import com.matt.commons.model.StatusResponse;
import com.matt.domain.PageResult;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 支持分页的远程调用工具类
 */
public class RemotePageCallUtil {

    // 全局ObjectMapper（可复用）
    private static final ObjectMapper objectMapper = new ObjectMapper();
    static {
        // 忽略未知字段，避免解析失败
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * 调用远程分页接口，返回通用分页结果
     * @param url 远程接口地址
     * @param pageNum 页码
     * @param pageSize 页大小
     * @param otherParams 其他业务参数（非分页参数）
     * @param ticket 认证票据
     * @param dataType 分页数据列表的元素类型（如ClassReviewVo.class）
     * @param errorMsg 错误提示
     * @param <T> 数据列表元素类型
     * @return 通用分页结果CommonPage<T>
     */
    public static <T> PageResult<T> callPage(
            String url,
            Integer pageNum,
            Integer pageSize,
            Map<String, Object> otherParams,
            String ticket,
            Class<T> dataType,
            String errorMsg) {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);

        try {
            // 1. 构建请求参数（合并分页参数和业务参数）
            Map<String, Object> params = new HashMap<>();
            params.put("pageNum", pageNum);       // 分页参数：页码
            params.put("pageSize", pageSize);     // 分页参数：页大小
            if (otherParams != null) {
                params.putAll(otherParams);       // 加入业务参数（如childrenId）
            }

            // 2. 设置请求头（JSON格式 + 认证ticket）
            httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
            if (ticket != null) {
                httpPost.setHeader("ticket", ticket); // 传递认证票据
            }

            // 3. 设置请求体（JSON格式）
            String jsonParams = objectMapper.writeValueAsString(params);
            StringEntity entity = new StringEntity(jsonParams, "UTF-8");
            httpPost.setEntity(entity);

            // 4. 执行请求
            CloseableHttpResponse response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();
            String responseJson = EntityUtils.toString(responseEntity, "UTF-8");

            // 5. 检查HTTP状态码
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new BusinessException("999999", errorMsg + "，HTTP状态码：" + response.getStatusLine().getStatusCode());
            }

            // 6. 解析响应为StatusResponse（假设远程接口统一返回StatusResponse格式）
            StatusResponse statusResponse = objectMapper.readValue(responseJson, StatusResponse.class);
            if (!statusResponse.getCode().equals(ErrorCode.SUCCESSFUL)) {
                throw new BusinessException(statusResponse.getCode(), statusResponse.getMsg());
            }

            // 7. 解析分页数据（远程接口返回的data是分页对象，包含records、total等字段）
            Map<String, Object> remotePageMap = (Map<String, Object>) statusResponse.getData();

            // 8. 构建通用分页结果CommonPage
            PageResult<T> resultPage = new PageResult<>();
            resultPage.setPageNum(pageNum);
            resultPage.setPageSize(pageSize);
            resultPage.setTotal(((Number) remotePageMap.get("total")).longValue()); // 总记录数

            // 计算总页数（或直接取远程返回的总页数）
            long total = resultPage.getTotal();
            int pages = (int) (total % pageSize == 0 ? total / pageSize : total / pageSize + 1);
            resultPage.setTotalPages(pages);

            // 9. 转换远程数据列表为目标类型（如ClassReview -> ClassReviewVo）
            List<Map<String, Object>> remoteRecords = (List<Map<String, Object>>) remotePageMap.get("records");
            if (remoteRecords != null) {
                // 将远程records（Map列表）转换为List<T>（如List<ClassReviewVo>）
                List<T> dataList = remoteRecords.stream()
                        .map(recordMap -> objectMapper.convertValue(recordMap, dataType))
                        .collect(Collectors.toList());
                resultPage.setList(dataList);
            }

            return resultPage;

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException("999998", errorMsg + "：" + e.getMessage());
        } finally {
            try {
                httpClient.close();
            } catch (Exception e) {
                // 忽略关闭异常
            }
        }
    }
}